import numpy as np
import pandas as pd
import os
import cv2


list = ["2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z"]

X = []
y_label = []
imgsize = [105, 96]
# imgsize = [75, 25]

def training_data(label, data_dir):
    if os.path.exists(data_dir):
        for img in os.listdir(data_dir):
                path = os.path.join(data_dir, img)  # 目录+文件名
                img = cv2.imread(path,cv2.IMREAD_COLOR) #读入图片
                img = cv2.resize(img,(imgsize[0],imgsize[1])) #设定图片像素维度
                X.append(np.array(img)) #X特征集
                y_label.append(str(label)) #y标签
    else:
        print(data_dir)

for label in list:
    training_data(label, f'img_cut/{label}')
print(len(X))
X = np.array(X) # 将X从列表转换为张量数组
X = X/255 # 将X张量归一化

from sklearn.preprocessing import LabelEncoder # 导入标签编码工具
from keras.utils import to_categorical # 导入One-hot编码工具

label_encoder = LabelEncoder()
y = label_encoder.fit_transform(y_label) # 标签编码
print(len(y))
y = to_categorical(y, 32) # 将标签转换为One-hot编码
# y = to_categorical(y, 36) # 将标签转换为One-hot编码


from sklearn.model_selection import train_test_split # 导入拆分工具

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,random_state=1)

#建立CNN算法模型
from keras import layers # 导入所有层
from keras import models # 导入所有模型
import joblib

# 贯序模型 ，序贯模型也是最简单的模型，就是像盖楼一样，一层一层往上堆叠着搭新的层。
cnn = models.Sequential()


# 激活函数接收神经元的输入信号，经过非线性变换后输出神经元的激活值。这个激活值通常被用于传递到下一层神经元或输出层中。激活函数可以增加模型的表达能力和拟合能力
cnn.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(imgsize[1],imgsize[0], 3)))# 输入卷积层
cnn.add(layers.MaxPooling2D((2, 2))) # 最大池化层

cnn.add(layers.Conv2D(64, (3, 3), activation='relu')) # 卷积层
cnn.add(layers.MaxPooling2D((2, 2))) # 最大池化层

cnn.add(layers.Conv2D(128, (3, 3), activation='relu')) # 卷积层
cnn.add(layers.MaxPooling2D((2, 2))) # 最大池化层

cnn.add(layers.Conv2D(128, (3, 3), activation='relu')) # 卷积层
cnn.add(layers.MaxPooling2D((2, 2))) # 最大池化层

cnn.add(layers.Flatten()) # 展平层

cnn.add(layers.Dense(512, activation='relu')) # 全连接层

# 32表示种类，激活函数使用Softmax
cnn.add(layers.Dense(32, activation='softmax')) # 分类输出层


# 设置优化器
cnn.compile(loss='categorical_crossentropy', # 损失函数
            optimizer='RMSprop',
            metrics=['acc']) # 评估指标

# X_train = X
# y_train = y
# 训练网络并把训练过程信息存入history对象
history = cnn.fit(X_train,y_train, #训练数据回答我！！
                  epochs=50, #训练轮次（梯度下降）
                  validation_split=0.2) #训练的同时进行验证



cnn.save(os.path.join(os.path.dirname("result"), 'model.h5'))


# y_test = y
# X_test = X
result = cnn.evaluate(X_test, y_test) #评估测试集上的准确率
print('CNN的测试准确率为',"{0:.2f}%".format(result[1]))


#


